package net.wendal.nutzbook.module;

import javax.servlet.http.HttpSession;

import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.QueryResult;
import org.nutz.dao.pager.Pager;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.Scope;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Attr;
import org.nutz.mvc.annotation.By;
import org.nutz.mvc.annotation.Fail;
import org.nutz.mvc.annotation.Filters;
import org.nutz.mvc.annotation.GET;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.filter.CheckSession;

import net.wendal.nutzbook.bean.User;
import net.wendal.nutzbook.bean.UserProfile;
import net.wendal.nutzbook.service.UserService;
import net.wendal.nutzbook.util.Toolkit;

@IocBean
@At("/user")
@Ok("json:{locked:'password|salt',ignoreNull:true}")
@Fail("http:500")
@Filters(@By(type=CheckSession.class, args= {"me", "/"}))
public class UserModule extends BaseModule {
	
	@Inject protected UserService userService;
	
	@GET
	@At("/login")
	@Filters
	@Ok("jsp:jsp.user.login")
	public void loginPage() {}
	
	@At("/")
	@Ok("jsp:jsp.user.list")
	public void list() {}
	
	@At
	public int count() {
		return dao.count(User.class);
	}
	
	@At
	@Filters()
	@POST
	public Object login(@Param("username")String username,
						@Param("password")String password,
						@Param("captcha")String captcha,
						@Attr(scope=Scope.SESSION, value="nutz_captcha")String _captcha,
						HttpSession session) {
		NutMap re = new NutMap();
		if (!Toolkit.checkCaptcha(_captcha, captcha)) {
			return re.setv("ok", false).setv("msg", "验证码错误");
		}
		int userId = userService.fetch(username, password);
		if (userId < 0) {
			return re.setv("ok", false).setv("msg", "用户名后密码错误");
		} else {
			session.setAttribute("me", userId);
			return re.setv("ok", true);
		}
	}
	
	@At
	@Ok(">>:/")
	public void logout(HttpSession session) {
		session.invalidate();
	}
	
	@At
	public Object add(@Param("..")User user) {
		NutMap re = new NutMap();
		String msg = checkUser(user, true);
		if (msg != null) {
			return re.setv("ok", false).setv("msg", msg);
		}
		user = userService.add(user.getName(), user.getPassword());
		return re.setv("ok", true).setv("data", user);
	}
	
	@At
	public Object update(@Param("password")String password, @Attr("me")int me) {
		if (Strings.isBlank(password) || password.length() < 6) {
			return new NutMap().setv("ok", false).setv("msg", "密码不符合规则");
		}
		userService.updatePassword(me, password);
		return new NutMap().setv("ok", true);
	}
	
	@At
	@Aop(TransAop.READ_COMMITTED)
	public Object delete(@Param("id")int id, @Attr("me")int me) {
		if (me == id) {
			return new NutMap().setv("ok", false).setv("msg", "不能删除当前用户");
		}
		dao.delete(User.class, id);
		dao.clear(UserProfile.class, Cnd.where("userId", "=", me));
		return new NutMap().setv("ok", true);
	}
	
	@At
	public Object query(@Param("name")String name, @Param("..")Pager pager) {
		Cnd cnd = Strings.isBlank(name) ? null : Cnd.where("name", "like", "%"+name+"%");
		QueryResult qr = new QueryResult();
		qr.setList(dao.query(User.class, cnd, pager));
		pager.setRecordCount(dao.count(User.class, cnd));
		qr.setPager(pager);
		return qr;
	}
	
	protected String checkUser(User user, boolean create) {
		if (user == null) {
			return "空对象";
		}
		if(create) {
			if(Strings.isBlank(user.getName()) || Strings.isBlank(user.getPassword())) {
				return "用户名/密码不能为空";
			}
		} else {
			if (Strings.isBlank(user.getPassword())) {
				return "密码不能为空";
			}
		}
		String passwd = user.getPassword().trim();
		if (6 > passwd.length() || passwd.length() > 12) {
			return "密码长度错误";
		}
		user.setPassword(passwd);
		if (create) {
			int count = dao.count(User.class, Cnd.where("name", "=", user.getName()));
			if (count != 0) {
				return "用户名已经存在";
			}
		} else {
			if (user.getId() < 1) {
				return "用户非法";
			}
		}
		if (user.getName() != null)
			user.setName(user.getName().trim());
		
		return null;
	}
}
